package yxy.game.pm2.active.module;

import org.joda.time.DateTime;
import yxy.apple.util.RandomUtility;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.*;
import yxy.cherry.data.string.GameString;
import yxy.game.pm2.active.ActiveUtil;
import yxy.game.pm2.active.module.actcontrol.activeControl;
import yxy.game.pm2.active.module.subordinateclass.Act_节日抽奖大奖纪录;
import yxy.game.pm2.active.module.subordinateclass.LimitGiftPackage;
import yxy.game.pm2.active.module.subordinateclass.TurntableRandomdataInfo;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.Item;
import yxy.game.pm2.bean.area.AreaBean;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.db.dao.MySQLCacheDAO;
import yxy.game.pm2.bean.module.AreaModule;
import yxy.game.pm2.bean.module.PlayerModule;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.bean.task.Task;
import yxy.game.pm2.message.ActiveMessage;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.mail.MailHandle;
import yxy.game.pm2.module.mail.MailTypeEnum;

import java.util.*;

/**
 * Author HYB
 */
public class ActiveModule_节日活动 extends PlayerModule {

    public static final int acttype = 22;

    private int logindays; // 登录天数
    private ArrayList<Integer> drawDay = new ArrayList<>();    //领取天数
    private DateTime updatetime; // 更新时间
    private int lotteryCount; // 抽奖次数
    private Map<Integer, Integer> exchanges = new HashMap<>(); // 兑换次数 <礼包id:兑换次数>
    private Map<Integer, Integer> integratReward = new HashMap<>(); // 积分奖励兑换 <id:状态>
    private int challenge; //挑战次数
    private Map<Integer, Integer> lotteryActiveDraw = new HashMap<>(); // 抽奖活跃领取 <id:状态>
    private int taskActiveNum; // 任务活跃值
    private Map<Integer, Integer> taskActiveStatus = new HashMap<>(); // 任务活跃领取状态
    private ArrayList<String> taskCodes = new ArrayList<>();// 任务列表
    private ArrayList<LimitGiftPackage> newlgps = new ArrayList<>();    //礼包信息

    public ArrayList<String> getTaskCodes() {
        return taskCodes;
    }

    public void setTaskCodes(ArrayList<String> taskCodes) {
        this.taskCodes = taskCodes;
    }

    public int getLogindays() {
        return logindays;
    }

    public void setLogindays(int logindays) {
        this.logindays = logindays;
    }

    public void addLogindays(int day) {
        this.logindays += day;
    }

    public ArrayList<Integer> getDrawDay() {
        return drawDay;
    }

    public void addDrawDay(int day) {
        this.drawDay.add(day);
        set();
    }

    public Map<Integer, Integer> getLotteryActiveDraw() {
        return lotteryActiveDraw;
    }

    public void setLotteryActiveDraw(Map<Integer, Integer> lotteryActiveDraw) {
        this.lotteryActiveDraw = lotteryActiveDraw;
    }

    public void setLotteryActiveDraw(int id) {
        this.lotteryActiveDraw.put(id, 1);
        set();
    }

    public void setDrawDay(ArrayList<Integer> drawDay) {
        this.drawDay = drawDay;
    }

    public DateTime getUpdatetime() {
        return updatetime;
    }

    public void setUpdatetime(DateTime updatetime) {
        this.updatetime = updatetime;
    }

    public Map<Integer, Integer> getExchanges() {
        return exchanges;
    }

    public int getLotteryCount() {
        return lotteryCount;
    }

    public void setLotteryCount(int lotteryCount) {
        this.lotteryCount = lotteryCount;
    }

    public void addLotteryCount(int lotteryCount) {
        this.lotteryCount += lotteryCount;
        set();
    }

    public int getTaskActiveNum() {
        return taskActiveNum;
    }

    public void addTaskActiveNum() {
        this.taskActiveNum++;
        set();
    }

    public void setTaskActiveNum(int taskActiveNum) {
        this.taskActiveNum = taskActiveNum;
    }

    public Map<Integer, Integer> getTaskActiveStatus() {
        return taskActiveStatus;
    }

    public void setTaskActiveStatus(Map<Integer, Integer> taskActiveStatus) {
        this.taskActiveStatus = taskActiveStatus;
    }

    public void setTaskActiveStatus(int id) {
        this.taskActiveStatus.put(id, 1);
        set();
    }

    public void addExchangeNum(int id, int num) {
        getExchanges().compute(id, (k, v) -> {
            if (v == null) {
                return +num;
            }
            return v + num;
        });
        set();
    }

    public void setExchanges(Map<Integer, Integer> exchanges) {
        this.exchanges = exchanges;
    }

    public Map<Integer, Integer> getIntegratReward() {
        return integratReward;
    }

    public void addIntegratReward(int id) {
        this.integratReward.put(id, 1);
        set();
    }

    public void setIntegratReward(Map<Integer, Integer> integratReward) {
        this.integratReward = integratReward;
    }

    public int getChallenge() {
        return challenge;
    }

    public void addChallenge() {
        this.challenge++;
        set();
    }

    public void setChallenge(int challenge) {
        this.challenge = challenge;
    }

    public ArrayList<LimitGiftPackage> getNewlgps() {
        return newlgps;
    }

    public void setNewlgps(ArrayList<LimitGiftPackage> newlgps) {
        this.newlgps = newlgps;
    }
    // fun======================================================================

    public void huishou() {
        try {
            //todo 活动关闭，清除背包的没消耗完的活动道具
            actturntabledate actturntabledate_ = DataCenter.getData(103, actturntabledate.class);
            int costid = actturntabledate_.getCostid1();//消耗的道具转盘令id
            //如果背包存在就转成对应物品邮件发送
            Currency currency = Item.get(getPlayerCode(), CurrencyType.CT_物品, costid);
            Currency currency1 = Item.get(getPlayerCode(), CurrencyType.CT_物品, 1043);//兼容以前的也要回收
            Currency currency2 = Item.get(getPlayerCode(), CurrencyType.CT_物品, 1042);//兼容以前的也要回收
            if (currency.getNumber() > 0 || currency1.getNumber() > 0 || currency2.getNumber() > 0 ) {
                List<Currency> list1 = new ArrayList<>();
                list1.add(currency);
                list1.add(currency1);
                list1.add(currency2);
                item item_ = DataCenter.getData(costid, item.class);
                item item_1 = DataCenter.getData(1043, item.class);
                item item_2 = DataCenter.getData(1042, item.class);
                new CurrencyHandle().cost(getPlayerCode(), CCReason.活动_节日_转盘令清空, list1);
                //邮件补偿
                List<Currency> list2 = new ArrayList<>();
                Currency reward = Currency.create(item_.getReclaimtype(), item_.getReclaimid(), currency.getNumber() * item_.getReclaimnum());
                Currency reward1 = Currency.create(item_1.getReclaimtype(), item_1.getReclaimid(), currency1.getNumber() * item_1.getReclaimnum());
                Currency reward2 = Currency.create(item_2.getReclaimtype(), item_2.getReclaimid(), currency2.getNumber() * item_2.getReclaimnum());
                if(reward!=null)list2.add(reward);
                if(reward1!=null)list2.add(reward1);
                if(reward2!=null)list2.add(reward2);
                String title = GameString.活动结束自动回收_title().getText();
                long num = currency.getNumber() + currency1.getNumber() + currency2.getNumber() ;
                String content = GameString.活动结束自动回收_msg("转盘", "" + num, "" + item_.getName(), "" + num * item_.getReclaimnum()).getText();
                new MailHandle().sendMail(getPlayerCode(), MailTypeEnum.Mail, title, content, CCReason.活动_节日_转盘令清空补偿, list2);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    static private ActiveModule_节日活动 create(String playerCode, activeControl sai) {
        if (!sai.isRuning()) {
            return null;
        }
        ActiveModule_节日活动 am = new ActiveModule_节日活动();
        am.setTimeline(sai.getTimeline());
        am.setPlayerCode(playerCode);
        am.setLogindays(ActiveUtil.days(sai.getTimeline().getStartTime(), DateTime.now()) + 1);
        am.setUpdatetime(DateTime.now());
        am.setLotteryCount(0);
        am.setChallenge(0);
        am.setTaskActiveNum(0);
        Map<String, atcholidayactive> datas = DataCenter.getAllData(atcholidayactive.class);
        for (atcholidayactive data : datas.values()) {
            int taskId = data.getTaskid();
            task taskdata = DataCenter.getData(taskId, task.class);
            Task task = Task.create(playerCode, taskdata);
            if (task != null) {
                am.getTaskCodes().add(task.getCode());
            }
        }
        Map<String, atcholidayshop2> alpmap = DataCenter.getAllData(atcholidayshop2.class);
        for (atcholidayshop2 alp : alpmap.values()) {
            LimitGiftPackage lgp = new LimitGiftPackage();
            lgp.setId(alp.getId());
            lgp.setGoodsid(alp.getPurchasever());
            lgp.setBuy(0);
            lgp.setLimit(alp.getNumber());
            am.getNewlgps().add(lgp);
        }
        am.set();
        return am;
    }


    private void update() {

        AreaBean ab = AreaModule.area(getPlayerCode());
        activeControl sai = activeControl.getAreaOneActionInfo(String.valueOf(ab.getAreaId()), String.valueOf(acttype));
        if (sai == null) {
            return;
        }
        if (!sai.isRuning()) {
            huishou();
            return;
        }

        // 区活动开启，但自己没开启，重置活动
        if (sai.running() && !running()) {
            Task.remove(getPlayerCode(), getTaskCodes());
            create(getPlayerCode(), sai);
        }

//        //关闭活动
//        if (!sai.running() && running()) {
//            setTimeline(sai.getTimeline());
//            set();
//        }
//        //开启活动
//        if (sai.running() && !running()) {
//            setTimeline(sai.getTimeline());
//            set();
//        }

        if (running()) {
            DateTime old = getUpdatetime();
            DateTime now = DateTime.now();

            int days = ActiveUtil.days(old, now);
            if (days >= 1) {
                addLogindays(days);
                setChallenge(0);
                Task.remove(getPlayerCode(), getTaskCodes());
                getTaskCodes().clear();

                Map<String, atcholidayactive> datas = DataCenter.getAllData(atcholidayactive.class);
                for (atcholidayactive data : datas.values()) {
                    int taskId = data.getTaskid();
                    task taskdata = DataCenter.getData(taskId, task.class);
                    Task task = Task.create(getPlayerCode(), taskdata);
                    if (task != null) {
                        getTaskCodes().add(task.getCode());
                    }
                }
                setUpdatetime(DateTime.now());
                this.set();
            }
        }
    }

    public DrawStatus buy(int goodsid) {
        for (LimitGiftPackage lgp : getNewlgps()) {
            if (lgp.getGoodsid() == goodsid) {
                int locknum = lgp.getLockorder().size();
                int buynum = lgp.getBuy();
                if (locknum + buynum < lgp.getLimit()) {
                    return DrawStatus.canget;
                }
            }
        }
        return DrawStatus.cannotget;
    }

    /**
     * 处理购买完成
     */
    public void handlebuy(int goodsid, String myorderid) {
        for (LimitGiftPackage lgp : getNewlgps()) {
            if (lgp.getGoodsid() == goodsid) {
                //解锁单
//                lgp.getLockorder().remove(myorderid);
                //增加购买次数
                int buynum = lgp.getBuy();
                buynum++;
                lgp.setBuy(buynum);
                set();
            }
        }
    }

    /**
     * 锁单
     */
    public void lockorder(int goodsid, String myorderid) {
        for (LimitGiftPackage lgp : getNewlgps()) {
            if (lgp.getGoodsid() == goodsid) {
//                lgp.getLockorder().put(myorderid, DateTime.now());
                set();
            }
        }
    }

    /**
     * 随机每个位置的道具
     *
     * @param areaId
     * @param name
     */
    public List<Currency> randomcur(int areaId, String name, int num) {
        Map<String, atcholidayturntable> actturntablemap = DataCenter.getAllData(atcholidayturntable.class);
        List<TurntableRandomdataInfo> trs = new ArrayList<>();
        actturntablemap.forEach((k, v) -> {
            TurntableRandomdataInfo tr = new TurntableRandomdataInfo();
            tr.setSequence(v.getId());
            Currency currency = Currency.create(v.getRewardtype(), v.getRewardid(), v.getRewardnum());
            tr.setCur(currency);
            tr.setWeight(v.getPercent());
            trs.add(tr);
        });
        return randomcur(trs, areaId, name, num);
    }

    public ArrayList<Currency> randomcur(List<TurntableRandomdataInfo> trs, int areaId, String name, int num) {
        ArrayList<Currency> curs = new ArrayList<>();
        for (int i = 0; i < num; i++) {
            TurntableRandomdataInfo tr2 = RandomUtility.randomWeight(trs);
            Currency cur = tr2.getCur();
            curs.add(cur);
            if (tr2.getSequence() == 1) {
                Act_节日抽奖大奖纪录 msg = Act_节日抽奖大奖纪录.create(areaId, name, cur);
                msg.add();
            }
        }
        return curs;
    }

    public Collection<ActiveMessage.AwardsInfo> getLog(int areaId) {
        List<ActiveMessage.AwardsInfo> list = new ArrayList<>();
        try {
            List<Act_节日抽奖大奖纪录> msgs = Act_节日抽奖大奖纪录.all(areaId);
            for (Act_节日抽奖大奖纪录 msg : msgs) {
                ActiveMessage.AwardsInfo.Builder ai = ActiveMessage.AwardsInfo.newBuilder();
                ai.setSequence(msg.getTime());
                ai.setItem(new CurrencyHandle().packItem(msg.getCur()));
                ai.setName(msg.getName());
                list.add(ai.build());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return list;
    }


    /**
     * 领取任务活跃奖励判断
     */
    public DrawStatus canGainTaskActiveReward(int id) {
        atcholidayactivecumulate data = DataCenter.getData(id, atcholidayactivecumulate.class);
        if (data == null) {
            return DrawStatus.cannotget;
        }
        int accumulate = data.getAccumulate();
        if (getTaskActiveNum() < accumulate) {
            return DrawStatus.cannotget;
        }
        Integer status = getTaskActiveStatus().getOrDefault(id, 0);
        if (status == 1) {
            return DrawStatus.hadget;
        }
        return DrawStatus.canget;
    }

    /**
     * 领取任务活跃奖励
     */
    public Collection<Currency> gainTaskActiveReward(int id) {
        atcholidayactivecumulate data = DataCenter.getData(id, atcholidayactivecumulate.class);
        return Currency.create(data.getRewardtype(), data.getRewardid(), data.getRewardnum());
    }

    /**
     * 领取转盘次数奖励判断
     */
    public DrawStatus canGainTurnTableActiveReward(int id) {
        atcholidayturntableactive data = DataCenter.getData(id, atcholidayturntableactive.class);
        if (data == null) {
            return DrawStatus.cannotget;
        }
        int accumulate = data.getAccumulate();
        if (getLotteryCount() < accumulate) {
            return DrawStatus.cannotget;
        }
        Integer status = getLotteryActiveDraw().getOrDefault(id, 0);
        if (status == 1) {
            return DrawStatus.hadget;
        }
        return DrawStatus.canget;
    }

    /**
     * 任务奖励判断
     */
    public DrawStatus canGainTaskReward(String taskCode) {
        Task task = Task.get(getPlayerCode(), taskCode);
        if (!task.isFinish() || task.isReward()) {
            return DrawStatus.cannotget;
        }
        return DrawStatus.canget;
    }

    /**
     * 签到奖励领取判断
     */
    public DrawStatus cangainreward(int id) {
        int logindays = getLogindays();
        ArrayList<Integer> getdays = getDrawDay();
        if (id > logindays) {
            return DrawStatus.cannotget;
        }
        if (getdays.contains(id)) {
            return DrawStatus.hadget;
        }
        return DrawStatus.canget;
    }

    /**
     * 签到奖励
     *
     * @return
     */
    public Collection<Currency> signDrawreward(int day) {
        atcholidaycheck asr = DataCenter.getData(day, atcholidaycheck.class);
        if (asr == null) {
            return null;
        }
        return Currency.create(asr.getRewardtype(), asr.getRewardid(), asr.getRewardnum());
    }

    /**
     * 兑换奖励领取判断
     */
    public DrawStatus canGainExchageReward(int id, int num) {
        atcholidayshop asr = DataCenter.getData(id, atcholidayshop.class);
        if (asr == null) {
            return DrawStatus.cannotget;
        }
        if (asr.getLimittype() == -1 && asr.getLimitnum() == 0) {
            return DrawStatus.canget;
        }
        Integer exchange = getExchanges().getOrDefault(id, 0);
        if (exchange + num <= asr.limitnum) {
            return DrawStatus.canget;
        }
        return DrawStatus.cannotget;
    }

    /**
     * 积分奖励领取判断
     */
    public DrawStatus canGainIntegratReward(int id) {
        Integer exchange = getIntegratReward().getOrDefault(id, 0);
        if (exchange == 1) {
            return DrawStatus.hadget;
        }
        atcholidaypoints data = DataCenter.getData(id, atcholidaypoints.class);
        if (data == null) {
            return DrawStatus.cannotget;
        }
        int group = data.getGroup();
        long number = Currency.number(getPlayerCode(), CurrencyType.CT_节日BOSS积分, 0, false);
        if (number < group) {
            return DrawStatus.cannotget;
        }
        return DrawStatus.canget;
    }

    // redis --------------------------------------------

    private static String key(String pcode) {
        return String.format("PLAYER:%s:ACTIVE:%S", pcode, acttype);
    }

    public void set() {
        try {
            String key1 = key(getPlayerCode());
            setv(key(getPlayerCode()), this);
            check();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    static public ActiveModule_节日活动 get(String playerCode, Boolean isNewPlayer) {

        try {
            ActiveModule_节日活动 module = getv(key(playerCode));

            //新用户不需要去查数据库
            if (module == null && !isNewPlayer) {
                module = MySQLCacheDAO.getV(key(playerCode), ActiveModule_节日活动.class);
                if (module != null) {
                    module.set();
                }//同步到redis
            }

            if (module == null) {
                AreaBean ab = AreaModule.area(playerCode);
                activeControl sai = activeControl.get(String.valueOf(ab.getAreaId()), String.valueOf(acttype));
                if (sai != null) {
                    module = create(playerCode, sai);
                }
            }
            if (module == null) return null;

            module.update();
            module.check();

            return module;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查看是否有可领取奖励 控制红点
     */
    public void check() {
        if (!running()) {
            new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.关闭);
        } else {
            new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.开启);
        }
    }

    //存储到数据库的方法
    public static void saveToDB(String playerCode) {
        try {
            String key = key(playerCode);
            if (touchBucket(key).isExists()) {
                ActiveModule_节日活动 activeModule_节日活动 = getv(key(playerCode));
                MySQLCacheDAO.setV(key, activeModule_节日活动);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //从redis移走数据的操作
    public static void removeAllFromRedis(String playerCode) {
        try {
            touchBucket(key(playerCode)).delete();
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }
    // lock==========================================================================

    @Override
    public String lockKey() {
        return String.format("lock:%s", key(getPlayerCode()));
    }
}
